package com.freight.order.serviceimpl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.freight.base.utils.AreaAddressUtil;
import com.freight.core.common.annotation.LogParam;
import com.freight.core.common.exception.LoginException;
import com.freight.core.common.utils.SecurityUtil;
import com.freight.core.common.utils.StringUtils;
import com.freight.core.entity.User;
import com.freight.order.dto.*;
import com.freight.order.mapper.OrderVoMapper;
import com.freight.order.service.IOrderVoService;
import com.freight.order.vo.*;
import com.freight.user.vo.VehicleInfoVo;
import com.freight.user.dto.CompanyDto;
import com.freight.user.dto.DriverDto;
import com.freight.user.service.ICompanyVoService;
import com.freight.user.service.IDriverVoService;
import com.freight.user.service.VehicleLicenseService;
import com.freight.user.util.UserDtoUtils;
import com.freight.user.util.UserVoUtils;
import com.freight.user.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单详情信息接口实现
 *
 * @author huyingtai
 */
@Slf4j
@Service
@Transactional
public class IOrderVoServiceImpl extends ServiceImpl<OrderVoMapper, OrderVo> implements IOrderVoService {

    @Autowired
    private OrderVoMapper orderVoMapper;

    @Autowired
    private IDriverVoService iDriverVoService;

    @Autowired
    private ICompanyVoService iCompanyVoService;

    @Autowired
    private VehicleLicenseService vehicleLicenseService;

    @Autowired
    private AreaAddressUtil areaAddressUtil;

    @Autowired
    private SecurityUtil securityUtil;



    public static int daysBetween(String smdate,String bdate)   {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        long between_days=0;
        try {
            cal.setTime(sdf.parse(smdate));
            long time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(bdate));
            long time2 = cal.getTimeInMillis();
            between_days=(time2-time1)/(1000*3600*24);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return Integer.parseInt(String.valueOf(between_days));
    }


    public static String calculation(String currentPeriod,String otherPeriods){
        DecimalFormat df   = new DecimalFormat("######0.00");
        if(otherPeriods.equals("0") || otherPeriods.equals("0.0") || otherPeriods.equals("0.00")){
            return "100.00";
        }else {
            String percentage = df.format((Double.valueOf(currentPeriod)-Double.valueOf(otherPeriods))/Double.valueOf(otherPeriods)*100.0);
            return percentage;
        }

    }

    public static void main(String[] args) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar calf = Calendar.getInstance();
        calf.setTime(new Date());
        calf.add(Calendar.DATE, -15);
        System.out.println(sdf.format(calf.getTime()));
    }

    /**
     * 根据状态获取公司订单详情
     *
     * @param page
     * @param searchOrderDto
     * @return
     */
    @Override
    @LogParam
    public Page<OrderVo> getOrderInfoByState(Page<OrderVo> page, SearchOrderDto searchOrderDto) {
        User u = securityUtil.getCurrUser();
        UserDtoUtils.getUserId(u);
        Page<OrderVo> res = null;
        List<DriverDetailInfoVo> drivers = null;
        List<CompanyDetailInfoVo> companys = null;
        Long[] iDrivers = null;
        Long[] iCompanys = null;
        if (searchOrderDto != null) {
            if (StringUtils.isNotBlank(searchOrderDto.getDriverName())) {
                DriverDto driverDto = new DriverDto();
                driverDto.setName(searchOrderDto.getDriverName());
                drivers = iDriverVoService.getDriverInfo(driverDto);
                if (drivers.size() != 0) {
                    iDrivers = new Long[drivers.size()];
                    for (int i = 0; i < drivers.size(); i++) {
                        iDrivers[i] = drivers.get(i).getUserId();
                    }
                } else {
                    iDrivers = new Long[1];
                    iDrivers[0] = -1L;
                }
            }
            if (StringUtils.isNotBlank(searchOrderDto.getCompanyName())) {
                CompanyDto companyDto = new CompanyDto();
                companyDto.setCompanyName(searchOrderDto.getCompanyName());
                companys = iCompanyVoService.getCompanyInfoVo(companyDto);
                if (companys.size() != 0) {
                    iCompanys = new Long[companys.size()];
                    for (int i = 0; i < companys.size(); i++) {
                        iCompanys[i] = companys.get(i).getUserId();
                    }
                } else {
                    iCompanys = new Long[1];
                    iCompanys[0] = -1L;
                }
            }
        }
        res = orderVoMapper.getAdminOrderVoByState(page, searchOrderDto);

        if (res.getRecords().size() != 0) {
            List<OrderVo> records = res.getRecords();
            areaAddressUtil.fillAreaAddress(records);
            HashSet<Long> driverIds = new HashSet<>();
            HashSet<Long> companyIds = new HashSet<>();
            HashSet<Long> vehicleIds = new HashSet<>();

            for (OrderVo record : records) {
                driverIds.add(record.getDriverUserId());
                companyIds.add(record.getCompanyUserId());
                vehicleIds.add(record.getVehicleId());

            }
            if (companyIds != null && companyIds.size() > 0) {
                Long[] lCompanyUserIds = companyIds.stream().toArray(Long[]::new);
                List<CompanyInfoVo> aCompanys = iCompanyVoService.getCompanyInfoVoByUserIds(lCompanyUserIds);
                HashMap<Long, CompanyInfoVo> aCompanyMaps = UserVoUtils.listToHashMap(aCompanys);
                for (OrderVo record : records) {
                    record.setCompanyInfoVo(aCompanyMaps.get(record.getCompanyUserId()));
                }
            }
            if (driverIds != null && driverIds.size() > 0) {
                Long[] iDriverIds = driverIds.stream().toArray(Long[]::new);
                List<DriverInfoVo> aDrivers = iDriverVoService.getDriverInfoByUserIds(iDriverIds);
                HashMap<Long, DriverInfoVo> aDriverMaps = UserVoUtils.listToHashMap(aDrivers);
                for (OrderVo record : records) {
                    record.setDriverInfoVo(aDriverMaps.get(record.getDriverUserId()));
                }
            }
            if (vehicleIds != null && vehicleIds.size() > 0) {
                Long[] iVehicleIds = vehicleIds.stream().toArray(Long[]::new);
                List<VehicleInfoVo> aVehicles = vehicleLicenseService.getVehicleInfoByUserIds(iVehicleIds);
                HashMap<Long, VehicleInfoVo> aVehicleMaps = UserVoUtils.listToHashMap(aVehicles);
                for (OrderVo record : records) {
                    record.setVehicleInfoVo(aVehicleMaps.get(record.getVehicleId()));
                }
            }
        }
        return res;
    }

    @Override
    public Page<OrderVo> getCompanyOrderInfoByState(Page<OrderVo> page, CompanySearchOrderDto searchOrderDto) {

        User u = securityUtil.getCurrUser();
        UserDtoUtils.getUserId(u);

        Page<OrderVo> res = orderVoMapper.getCompanyOrderVoByState(page, u.getId(), searchOrderDto);

        if (res.getRecords().size() != 0) {
            List<OrderVo> records = res.getRecords();
            areaAddressUtil.fillAreaAddress(records);
            HashSet<Long> driverIds = new HashSet<>();
            HashSet<Long> companyIds = new HashSet<>();
            HashSet<Long> vehicleIds = new HashSet<>();
            for (OrderVo record : records) {
                driverIds.add(record.getDriverUserId());
                companyIds.add(record.getCompanyUserId());
                vehicleIds.add(record.getVehicleId());
            }

            if (companyIds != null && companyIds.size() > 0) {
                Long[] lCompanyUserIds = companyIds.stream().toArray(Long[]::new);
                List<CompanyInfoVo> aCompanys = iCompanyVoService.getCompanyInfoVoByUserIds(lCompanyUserIds);
                HashMap<Long, CompanyInfoVo> aCompanyMaps = UserVoUtils.listToHashMap(aCompanys);
                for (OrderVo record : records) {
                    record.setCompanyInfoVo(aCompanyMaps.get(record.getCompanyUserId()));
                }
            }
            if (driverIds != null && driverIds.size() > 0) {
                Long[] iDriverIds = driverIds.stream().toArray(Long[]::new);
                List<DriverInfoVo> aDrivers = iDriverVoService.getDriverInfoByUserIds(iDriverIds);
                HashMap<Long, DriverInfoVo> aDriverMaps = UserVoUtils.listToHashMap(aDrivers);
                for (OrderVo record : records)
                {
                    record.setDriverInfoVo(aDriverMaps.get(record.getDriverUserId()));
                }
            }
            if (vehicleIds != null && vehicleIds.size() > 0) {
                Long[] iVehicleIds = vehicleIds.stream().toArray(Long[]::new);
                List<VehicleInfoVo> aVehicles = vehicleLicenseService.getVehicleInfoByUserIds(iVehicleIds);
                HashMap<Long, VehicleInfoVo> aVehicleMaps = UserVoUtils.listToHashMap(aVehicles);
                for (OrderVo record : records) {
                    record.setVehicleInfoVo(aVehicleMaps.get(record.getVehicleId()));
                }
            }
        }
        return res;
    }

    @Override
    public Page<OrderVo> getDriverOrderInfoByState(Page<OrderVo> page, String[] orderState) {
        User u = securityUtil.getCurrUser();
        UserDtoUtils.getUserId(u);

        Page<OrderVo> res = orderVoMapper.getDriverOrderVoByState(page, u.getId(), orderState);

        if (res.getRecords().size() != 0) {
            List<OrderVo> records = res.getRecords();
            areaAddressUtil.fillAreaAddress(records);
            HashSet<Long> driverIds = new HashSet<>();
            HashSet<Long> companyIds = new HashSet<>();
            HashSet<Long> vehicleIds = new HashSet<>();
            for (OrderVo record : records) {
                driverIds.add(record.getDriverUserId());
                companyIds.add(record.getCompanyUserId());
                vehicleIds.add(record.getVehicleId());

            }
            if (companyIds != null && companyIds.size() > 0) {
                Long[] lCompanyUserIds = companyIds.stream().toArray(Long[]::new);
                List<CompanyInfoVo> aCompanys = iCompanyVoService.getCompanyInfoVoByUserIds(lCompanyUserIds);
                HashMap<Long, CompanyInfoVo> aCompanyMaps = UserVoUtils.listToHashMap(aCompanys);
                for (OrderVo record : records) {

                    record.setCompanyInfoVo(aCompanyMaps.get(record.getCompanyUserId()));
                }
            }
            if (driverIds != null && driverIds.size() > 0) {
                Long[] iDriverIds = driverIds.stream().toArray(Long[]::new);
                List<DriverInfoVo> aDrivers = iDriverVoService.getDriverInfoByUserIds(iDriverIds);
                HashMap<Long, DriverInfoVo> aDriverMaps = UserVoUtils.listToHashMap(aDrivers);
                for (OrderVo record : records){
                    record.setDriverInfoVo(aDriverMaps.get(record.getDriverUserId()));
                }
            }
            if (vehicleIds != null && vehicleIds.size() > 0) {
                Long[] iVehicleIds = vehicleIds.stream().toArray(Long[]::new);
                List<VehicleInfoVo> aVehicles = vehicleLicenseService.getVehicleInfoByUserIds(iVehicleIds);
                HashMap<Long, VehicleInfoVo> aVehicleMaps = UserVoUtils.listToHashMap(aVehicles);
                for (OrderVo record : records) {
                    record.setVehicleInfoVo(aVehicleMaps.get(record.getVehicleId()));
                }
            }
        }
        return res;
    }


    @Override
    public Page<DriverOrderCompanyVo> getDriverOrderCompanyInfo(Page<DriverOrderCompanyVo> page) {
        User u = securityUtil.getCurrUser();
        if (u == null) {
            throw new LoginException("登入失效或尚未登入，请先登入");
        }
        Page<DriverOrderCompanyVo> res = orderVoMapper.getDriverOrderCompanyInfo(page, u.getId());
        if (res.getRecords().size() != 0) {
            List<DriverOrderCompanyVo> records = res.getRecords();
            HashSet<Long> companyUserIds = new HashSet<>();
            for (DriverOrderCompanyVo record : records) {
                companyUserIds.add(record.getCompanyUserId());
            }
            Long[] comUserIds = companyUserIds.stream().toArray(Long[]::new);

            List<AppointCompanyInfoVo> aCompanys = iCompanyVoService.getAppointCompanyInfoVoByUserIds(comUserIds);

            HashMap<Long, AppointCompanyInfoVo> aCompanyMaps = UserVoUtils.listToHashMap(aCompanys);
            for (DriverOrderCompanyVo record : records) {
                record.setAppointCompanyInfoVo(aCompanyMaps.get(record.getCompanyUserId()));

            }
        }
        return res;
    }

    @Override
    public OrderVo getOrderVoInfo(Long orderId) {
        if (orderId == null) {
            throw new LoginException("请先登入 或传入订单id");
        }
        OrderVo res = orderVoMapper.getOrderInfoVo(orderId);

        if (res != null) {

            CompanyInfoVo ic = iCompanyVoService.getCompanyInfoVoByUserId(res.getCompanyUserId());
            DriverInfoVo id = iDriverVoService.getDriverInfoByUserId(res.getDriverUserId());
            VehicleInfoVo iv = vehicleLicenseService.getVehicleInfoByUserId(res.getVehicleId());

            res.setDriverInfoVo(id);
            res.setCompanyInfoVo(ic);
            res.setVehicleInfoVo(iv);

            areaAddressUtil.fillAreaAddress(res);
        }
        return res;
    }

}